feat: Add methods for cozy-app settings and instance settings manipulation#1460
feat: Add methods for cozy-app settings and instance settings manipulation#1460
Conversation
6b4ac6c to
4a9b541
Compare
8092419 to
0af2607
Compare
| ) => { | ||
| const query = getQuery(slug) | ||
|
|
||
| const currentSettingsResult = await client.query( |
There was a problem hiding this comment.
Wouldn't it be relevant to use afetchQueryAndGetFromState here? This would look more like a useQuery by retrieving the cache if it exists
There was a problem hiding this comment.
Sorry I made the edit this morning but did not pushed it yet seems some discussion are still in progress
I pushed theme here, but CI will fail due to types error: https://github.com/cozy/cozy-client/compare/0af2607eabfdcc3fe08b06f560166123a320b91d..c44f83a86d7b55513e3bdffbbff1ca9edf62cbb6
There was a problem hiding this comment.
(cf #931 et l'autre issue liée pour pourquoi cette méthode pour le moment)
bd57188 to
ef64bdc
Compare
In our cozy-apps, we often need to handle specific settings for each cozy-app. This includes: - io.cozy.settings/io.cozy.settings.instance - io.cozy.settings/io.cozy.settings.bitwarden - io.cozy.home.settings - io.cozy.coachco2.settings - io.cozy.mespapiers.settings In the current code base, all those access are made with different code that can be heterogeneous We want to mutualize those access into two methods: - client.getSetting(slug, key) - client.saveAfterFetchSetting(slug, key, value) `getSetting` is responsible to retrieve the given `key` from a specific cozy-app setting `saveAfterFetchSetting` is responsible to update the given `key` for a specific cozy-app setting Note that `saveAfterFetchSetting` will first fetch the cozy-app settings before editing and saving them. This prevents from having to pass existing settings as parameter and also this ensure we always inject up to date data into the database
In previous commit we added `getSetting` and `saveAfterFetchSetting` methods into cozy-client Those methods are not Reactive so we always need to call `getSetting` on demand to have fresh data. Also `saveAfterFetchSetting` will always fetch data before updating and saving them into database even if the data is already up-to-date In order to improve this, this commit implements the `useSetting` hook that relies on `useQuery` and `useMutation` to keep data up-to-date and to mutate them
`.query` would return `undefined` if called under the fetch policy's delay We want to retrieve the data from local storage in that scenario So the solution is to call `.fetchQueryAndGetFromState` instead of `.query`
ef64bdc to
18a6c8f
Compare
fefd7e3 to
e87a674
Compare
| import fetchPolicies from '../policies' | ||
| import { Q } from '../queries/dsl' | ||
|
|
||
| const defaultFetchPolicy = fetchPolicies.olderThan(60 * 60 * 1000) |
There was a problem hiding this comment.
I'm thinking about this default fetch policy. Maybe it is too long ? I do not have any use case now to explain (😅) but I have the feeling that with 1 hour we can get outdated setting value where we de not want outdated setting value.
Maybe it should be short but enough to avoid 2 requests when doing a getSetting + saveAfterFetchSetting? Like 10 seconds?
Oh you already changed it in a next commit perfect.
| * | ||
| * @param {CozyClient} client - Cozy client instance | ||
| * @param {string} slug - the cozy-app's slug containing the setting (can be 'instance' for global settings) | ||
| * @param {string} key - The name of the setting to retrieve |
There was a problem hiding this comment.
Maybe having an array of keys could have been useful
There was a problem hiding this comment.
Why not, I'll try to add this
There was a problem hiding this comment.
I have this in my mind since yesterday but I'm struggling on choosing the best API.
Declaration
For the declaration I imagine the following possibilities:
Use same hook for both single string param or multiple array param
const { value } = useSetting('home', 'mysetting')
// value = 'some_value'
const { value } = useSetting('home', ['mysetting1', 'mysetting2'])
// value = {
// mysetting1: 'some_value_1',
// mysetting2: 'some_value_2'
// }Use a different hooks for single and multiple params
const { value } = useSetting('home', 'mysetting')
const { values } = useSettings('home', ['mysetting1', 'mysetting2'])Use an object instead of an array to declare default values (but I we may remove the default value thing, I think I can forget this option)
const { value } = useSetting('home', 'mysetting')
const { values } = useSettings('home', {
mysetting1: 'defaultValue1',
mysetting2': 'defaultValue2'
})Mutation
Mutation is getting harder to approach
Should we return multiple save methods for each key?
const { value, savemysetting1, savemysetting2} = useSetting('home', ['mysetting1', 'mysetting2'])
savemysetting1('value1')
savemysetting2('value2')or
const { value, save } = useSetting('home', ['mysetting1', 'mysetting2'])
save.mysetting1('value1')
save.mysetting2('value2')This constrains the API and so prevents errors, but sadly this also prevents mutating multiple settings at once
Should we return a save that takes an objet?
const { value, save} = useSetting('home', ['mysetting1', 'mysetting2', 'mysetting3'])
savemysetting1({
mysetting1: 'value1',
mysetting3: 'value3'
})This allow mutating multiple settings at once, but this makes the API less contraint and I'm wondering if we should allow inserting new keys or make a code that throw a specific error is the method is called with keys that are not present in the initial array?
There was a problem hiding this comment.
I made a proposal here: dcb23c5
(I still have to update documentation)
Usage would be:
Hook
const { value, save } = useSetting('home', ['mysetting1', 'mysetting2'])
...
// ✅ Valid
save({
mySetting1: 'newValue1',
mySetting2: 'newValue2'
})
// ✅ Valid
save({
mySetting1: 'newValue1'
})
// ❌ Not valid because new key inserted
save({
mySetting1: 'newValue1',
mySetting2: 'newValue2',
mySetting3: 'newValue3'
})Get
const result = await client.getSetting('home', ['mysetting1', 'mysetting2'])
console.log(result.mysetting1)
console.log(result.mysetting2)Save
// With raw value
await client.saveAfterFetchSetting(
'instance',
{
some_instance_key: 'some_new_instance_value',
some_instance_key2: 'some_new_instance_value_2'
}
)
// With a method
await client.saveAfterFetchSetting(
'instance',
currentValue => ({
...currentValue,
some_instance_key: currentValue.some_instance_key + 1,
some_instance_key2: 'some_new_instance_value_2'
}),
['some_instance_key']
)When using a method we must pass a setterKeys parameters so the save method can still extract correct values. I would prefer not to have this parameter but I did not find a better way 😕
There was a problem hiding this comment.
I updated the cozy-home PR with the new multiple-settings API: linagora/cozy-home@e20239d
| * | ||
| * If the query is called under the fetch policy's delay, then the query | ||
| * is not executed and nothing is returned. If you need a result anyway, | ||
| * please use `fetchQueryAndGetFromState` instead |
e87a674 to
582f832
Compare
paultranvan
left a comment
There was a problem hiding this comment.
Thanks for the work! Hopefully the beginning of future great contributions 😄
dcb23c5 to
de7a8c6
Compare
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings
`cozy-client` has been upgraded to `46.9.0` to retrieve the new useSettings hook Related PR: linagora/cozy-client#1460
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings
`cozy-client` has been upgraded to `46.9.1` to retrieve the new `getSettings()` and `saveAfterFetchSettings()` methods Related PR: linagora/cozy-client#1460
`cozy-client` has been upgraded to `46.9.1` to retrieve the new `getSettings()` and `saveAfterFetchSettings()` methods Related PR: linagora/cozy-client#1460
`cozy-client` has been upgraded to `46.9.1` to retrieve the new `getSettings()` and `saveAfterFetchSettings()` methods Related PR: linagora/cozy-client#1460
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings
In linagora/cozy-client#1460 we implemented a new `useSettings` hook This hook can be used in `DefaultRedirectionSnackbar` in order to simplify code and homogenize the way we access cozy-apps settings

In our cozy-apps, we often need to handle specific settings for each cozy-app. This includes:
In the current code base, all those access are made with different code that can be heterogeneous
We want to mutualize those access into two methods:
getSettingis responsible to retrieve the givenkeyfrom a specific cozy-app settingsaveAfterFetchSettingis responsible to update the givenkeyfor a specific cozy-app settingNote that
saveAfterFetchSettingwill first fetch the cozy-app settings before editing and saving them. This prevents from having to pass existing settings as parameter and also this ensure we always inject up to date data into the databaseAlso, in order to have Reactive methods, this PR also implements the
useSettinghook that relies onuseQueryanduseMutationto keep data up-to-date and to mutate themHook usage:
Get method usage:
Save method usage:
TODO:
What can be improved:
onSuccessandonErrorcallbacks that can be passed touseMutation()